﻿using System;
using System.Text;
using System.Linq;
using SampleApp.Domain;
using SampleApp.Data;
using System.Collections.Generic;
using COM.Service;

namespace SampleApp.Service
{
    public class SysUserService : ISysUserService
    {
        private ISysUserRepository sysUserRepository;
        private ISysUserRoleRepository sysUserRoleRepository;
        private IRuntimeService runtimeService;
        private ISaltHashService saltHashService;
        private IDataCacheService dataCacheService;
        public SysUserService(IRuntimeService runtimeService,IDataCacheService dataCacheService, ISaltHashService saltHashService, ISysUserRoleRepository sysUserRoleRepository, ISysUserRepository sysUserRepository)
        {
            this.runtimeService = runtimeService;
            this.sysUserRepository = sysUserRepository;
            this.sysUserRoleRepository = sysUserRoleRepository;
            this.saltHashService = saltHashService;
            this.dataCacheService = dataCacheService;
        }

        public List<SysUser> GetSysUserListByDept(string deptCode)
        {
            var q = this.sysUserRepository.GetMany(i => i.DeptCode == deptCode);
            return q.ToList();
        }

        public List<SysUser> GetSysUserListFromDatabase()
        {
            var q = this.sysUserRepository.GetMany(i => true);
            return q.ToList();
        }

        public List<SysUser> GetSysUserList()
        {
            return this.dataCacheService.UserList;
        }


        public SysUser GetSysUserByCode(string UserCode)
        {
            return this.sysUserRepository.GetByID(UserCode);
        }

        public void CreateSysUser(SysUser sysUser)
        {
            string hash = string.Empty;
            this.saltHashService.GetHashWithSaltString(sysUser.UserCode, out hash);
            sysUser.Password = hash;

            this.sysUserRepository.Add(sysUser);
            this.runtimeService.UnitOfWork.Commit();
        }


        public void DeleteSysUser(string UserCode)
        {
            var existsUser = this.GetSysUserByCode(UserCode);
            this.sysUserRepository.Delete(existsUser);
            this.runtimeService.UnitOfWork.Commit();
        }

        public void UpdateSysUser(SysUser sysUser)
        {
            var exists = this.GetSysUserByCode(sysUser.UserCode);
            this.sysUserRepository.SetValues(sysUser, exists);
            this.runtimeService.UnitOfWork.Commit();
        }



        public List<string> GetRoleListByUser(string userCode)
        {
            var user = this.sysUserRepository.GetUserWithRoleList(userCode);
            return user.UserRoleList.Select(i => i.RoleID).ToList();
        }

        public void SetUserRole(string userCode, List<string> roleList)
        {
            var list = this.sysUserRoleRepository.GetMany(i => i.UserCode == userCode).ToList();
            list.ForEach(i => this.sysUserRoleRepository.Delete(i));
            var roleListAdd = roleList.Select(i=>new SysUserRole(){RoleID = i,UserCode=userCode,UserRoleID = Guid.NewGuid()}).ToList();
            roleListAdd.ForEach(i => this.sysUserRoleRepository.Add(i));
            this.runtimeService.UnitOfWork.Commit();
        }


        public bool CheckUserPassword(string userCode, string password)
        {
            var user = this.GetSysUserByCode(userCode);
            if (user == null)
                return false;

            if (string.IsNullOrEmpty(password))
                password = "_NULL_PASSWORD_";

            return this.saltHashService.VerifyHashWithSaltString(password.TrimOrEmpty(), user.Password.TrimOrEmpty());
 
        }

        public void UpdatePartialSysUser(SysUser sysUser)
        {
            this.sysUserRepository.PreUpdatePartial(sysUser);
            this.runtimeService.UnitOfWork.Commit();
        }


        public void SetUserPassword(string userCode, string password)
        {
            var user = this.GetSysUserByCode(userCode);
            password = password.TrimOrEmpty();
            if (string.IsNullOrEmpty(password))
                password = "_NULL_PASSWORD_";

            string hash = string.Empty;
            this.saltHashService.GetHashWithSaltString(password, out hash);
            user.Password = hash;
            this.runtimeService.UnitOfWork.Commit();
        }


    }
}
